package cn.edu.nuc.ssm.service.impl;

import cn.edu.nuc.ssm.dao.*;
import cn.edu.nuc.ssm.entity.*;
import cn.edu.nuc.ssm.service.JizhangService;
import cn.edu.nuc.ssm.util.MyMath;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * Created by Administrator on 2017/4/6.
 */
@Service
public class JizhangServiceImpl implements JizhangService{

    private static Logger logger = LoggerFactory.getLogger(JizhangServiceImpl.class);

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    private CategoryMapper categoryMapper;

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    private PayIncomeMapper payIncomeMapper;

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    private AccountMapper accountMapper;

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    private AccountTransferMapper accountTransferMapper;

    @SuppressWarnings("SpringJavaAutowiringInspection")
    @Autowired
    private DoListMapper doListMapper;

    @Autowired
    private BorrowMoneyManagerMapper borrowMoneyManagerMapper;

    @Transactional(readOnly=true ,timeout = 30)
    public List<Category> findBlongZhicuCategory(Integer uid){
        //这里 1 表示支出

        List<Category> list = categoryMapper.findbyCategoryBelongAndUid(1,uid);
        return list;
    }

    @Override
    @Transactional(readOnly=true ,timeout = 30)
    public List<Category> findBlongSouruCategory(Integer uid) {
        //这里 2 表示收入

        List<Category> list = categoryMapper.findbyCategoryBelongAndUid(2,uid);
        return list;
    }

    @Override
    @Transactional(readOnly = false,timeout = 30)
    public int zhicuMoney(PayIncome payIncome, Account account) {

        //查找帐户
        Account findAccount = accountMapper.findbyIdAnduid(account.getId(), account.getUid());
        if (findAccount==null){

            throw new RuntimeException("插入支出数据发生错误");
        }

        if(findAccount.getRemainMoney().subtract(payIncome.getMoney()).doubleValue() < 0  ){

            throw new RuntimeException("账户余额不足");
        }

        //插入支付的数据
        int i = payIncomeMapper.insertZhichu(payIncome);
        if( i <= 0){
            throw new RuntimeException("插入支出数据发生错误");
        }
        BigDecimal zhichuMoney = payIncome.getMoney();
        //更新帐户中的数据
        subAccountMoney(findAccount,zhichuMoney);
        int i1 = accountMapper.modifyMoney(findAccount.getId(), findAccount.getRemainMoney(), findAccount.getInMoney(), findAccount.getOutMoney());
        if( i1 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }
        DoList doList = new DoList();
        doList.setUseId(findAccount.getUid());
        String categoryName = categoryMapper.findbyId( payIncome.getCtid().intValue()).getName();
        doList.setDoName(categoryName );
        doList.setDetail(payIncome.getDetail());
        doList.setRecordDate(payIncome.getDate());
        doList.setRecordMoney(payIncome.getMoney());
        doList.setAccId(account.getId());
        doList.setFlag(1);

        doListMapper.insert(doList);
        return 1;
    }

    @Override
    @Transactional(readOnly = false,timeout = 30)
    public int shouruMoney(PayIncome payIncome, Account account) {

        //查找帐户

        Account findAccount = accountMapper.findbyIdAnduid(account.getId(), account.getUid());

        if (findAccount==null){

            throw new RuntimeException("插入支出数据发生错误");
        }
        //插入支付的数据
        int i = payIncomeMapper.insertShouru(payIncome);
        if( i <= 0){
            throw new RuntimeException("插入支出数据发生错误");
        }
        BigDecimal shouruMoney = payIncome.getMoney();
        //更新帐户中的数据
        addUpdateAccountMoney(findAccount,shouruMoney);
        int i1 = accountMapper.modifyMoney(findAccount.getId(), findAccount.getRemainMoney(), findAccount.getInMoney(), findAccount.getOutMoney());
        if( i1 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }
        DoList doList = new DoList();
        doList.setUseId(findAccount.getUid());
        String categoryName = categoryMapper.findbyId( payIncome.getCtid().intValue()).getName();
        doList.setDoName(categoryName );
        doList.setDetail(payIncome.getDetail());
        doList.setRecordDate(payIncome.getDate());
        doList.setRecordMoney(payIncome.getMoney());
        doList.setAccId(account.getId());
        doList.setFlag(2);
        doListMapper.insert(doList);
        return 1;
    }


    @Override
    @Transactional(readOnly = false,timeout = 30)
    public int zhuanZhangMoney(AccountTransfer accountTransfer) {

        //查找帐户

        Account findInAccount = accountMapper.findbyId(accountTransfer.getAccountInId());
        Account findOutAccount = accountMapper.findbyId(accountTransfer.getAccountOutId());

        if(findOutAccount.getRemainMoney().subtract(accountTransfer.getTransferMoney()).doubleValue() < 0  ){

            throw new RuntimeException("账户余额不足");
        }

        if (findInAccount==null||findOutAccount==null){

            throw new RuntimeException("插入支出数据发生错误");
        }
        int insert = accountTransferMapper.insert(accountTransfer);
        //插入支付的数据
        if( insert <= 0){
            throw new RuntimeException("插入支出数据发生错误");
        }
        BigDecimal zhuangZhangMoney = accountTransfer.getTransferMoney();
        //更新转入帐户中的数据
        addUpdateAccountMoney(findInAccount,zhuangZhangMoney);
        int i1 = accountMapper.modifyMoney(findInAccount.getId(), findInAccount.getRemainMoney(), findInAccount.getInMoney(), findInAccount.getOutMoney());
        if( i1 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }
        //更新转入帐户中的数据
        subAccountMoney(findOutAccount,zhuangZhangMoney);
        int i2 = accountMapper.modifyMoney(findOutAccount.getId(), findOutAccount.getRemainMoney(), findOutAccount.getInMoney(), findOutAccount.getOutMoney());
        if( i2 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }

        DoList doList = new DoList();
        doList.setUseId(accountTransfer.getUid());

        doList.setDoName("转账");
        doList.setDetail(accountTransfer.getDetail());
        doList.setRecordDate(accountTransfer.getTransferDate());
        doList.setRecordMoney(accountTransfer.getTransferMoney());
        doList.setAccId(findInAccount.getId());
        doList.setAccOutId(findOutAccount.getId());
        doList.setFlag(3);
        doListMapper.insert(doList);
        return 1;
    }

    @Override
    @Transactional(readOnly = false,timeout = 30)
    public int jiancuMoney(AccountTransfer accountTransfer) {

        //查找帐户

        Account zaiquanAccount = accountMapper.findbyId(accountTransfer.getAccountInId());
        Account findOutaccount = accountMapper.findbyId(accountTransfer.getAccountOutId());

        if(findOutaccount.getRemainMoney().subtract(accountTransfer.getTransferMoney()).doubleValue() < 0  ){

            throw new RuntimeException("账户余额不足");
        }


        if (zaiquanAccount==null||findOutaccount==null){

            throw new RuntimeException("数据发生错误");
        }
        int insert = accountTransferMapper.insert(accountTransfer);
        //
        if( insert <= 0){

            throw new RuntimeException("数据发生错误");
        }
        BigDecimal zaiquanMoney = accountTransfer.getTransferMoney();
        //更新债权帐户中的数据
        addUpdateAccountMoney(zaiquanAccount,zaiquanMoney);
        int i1 = accountMapper.modifyMoney(zaiquanAccount.getId(), zaiquanAccount.getRemainMoney(), zaiquanAccount.getInMoney(), zaiquanAccount.getOutMoney());
        if( i1 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }
        //更新转出帐户中的数据
        subAccountMoney(findOutaccount,zaiquanMoney);
        int i2 = accountMapper.modifyMoney(findOutaccount.getId(), findOutaccount.getRemainMoney(), findOutaccount.getInMoney(), findOutaccount.getOutMoney());
        if( i2 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }

        DoList doList = new DoList();
        doList.setUseId(accountTransfer.getUid());

        doList.setDoName("转账");
        doList.setDetail(accountTransfer.getDetail());
        doList.setRecordDate(accountTransfer.getTransferDate());
        doList.setRecordMoney(accountTransfer.getTransferMoney());
        doList.setAccId(zaiquanAccount.getId());
        doList.setAccOutId(findOutaccount.getId());
        doList.setFlag(5);
        int insert1 = doListMapper.insert(doList);

        if( insert1 <= 0){
            throw new RuntimeException("数据发生错误");
        }

        BorrowMoneyManager borrowMoneyManager =
                new BorrowMoneyManager(accountTransfer.getUid(),accountTransfer.getTransferMoney(),0,accountTransfer.getDetail(),accountTransfer.getTransferDate());

        int insert2 = borrowMoneyManagerMapper.insert(borrowMoneyManager);
        if( insert2 <= 0){
            throw new RuntimeException("数据发生错误");
        }


        return 1;
    }

    @Override
    @Transactional(readOnly = false,timeout = 30)
    public int jianruMoney(AccountTransfer accountTransfer) {

        //查找帐户
        Account fuzaiAccount = accountMapper.findbyId(accountTransfer.getAccountOutId());
        Account findInccount = accountMapper.findbyId(accountTransfer.getAccountInId());

        if (fuzaiAccount==null||findInccount==null){

            throw new RuntimeException("数据发生错误");
        }
        int insert = accountTransferMapper.insert(accountTransfer);
        //插入支付的数据
        if( insert <= 0){

            throw new RuntimeException("数据发生错误");
        }
        BigDecimal fuzaiMoney = accountTransfer.getTransferMoney();
        //更新负债帐户中的数据
        addUpdateAccountMoney(fuzaiAccount,fuzaiMoney);
        int i1 = accountMapper.modifyMoney(fuzaiAccount.getId(), fuzaiAccount.getRemainMoney(), fuzaiAccount.getInMoney(), fuzaiAccount.getOutMoney());
        if( i1 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }
        //更新转入帐户中的数据
        addUpdateAccountMoney(findInccount,fuzaiMoney);
        int i2 = accountMapper.modifyMoney(findInccount.getId(), findInccount.getRemainMoney(), findInccount.getInMoney(), findInccount.getOutMoney());
        if( i2 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }

        DoList doList = new DoList();
        doList.setUseId(accountTransfer.getUid());

        doList.setDoName("转账");
        doList.setDetail(accountTransfer.getDetail());
        doList.setRecordDate(accountTransfer.getTransferDate());
        doList.setRecordMoney(accountTransfer.getTransferMoney());
        doList.setAccId(findInccount.getId());
        doList.setAccOutId(fuzaiAccount.getId());
        doList.setFlag(4);
        int insert1 = doListMapper.insert(doList);

        if( insert1 <= 0){
            throw new RuntimeException("数据发生错误");
        }



        return 1;
    }

    @Override
    @Transactional(readOnly = false,timeout = 30)
    public int huankuanMoney(AccountTransfer accountTransfer) {

        //查找帐户

        Account zaiquanAccount = accountMapper.findbyId(accountTransfer.getAccountInId());
        Account findOutaccount = accountMapper.findbyId(accountTransfer.getAccountOutId());

        if(findOutaccount.getRemainMoney().subtract(accountTransfer.getTransferMoney()).doubleValue() < 0  ){

            throw new RuntimeException("还账金额不对");
        }

        if (zaiquanAccount==null||findOutaccount==null){

            throw new RuntimeException("数据发生错误");
        }
        int insert = accountTransferMapper.insert(accountTransfer);
        //
        if( insert <= 0){

            throw new RuntimeException("数据发生错误");
        }
        BigDecimal huankuanMoney = accountTransfer.getTransferMoney();
        //更新负债帐户中的数据
        subAccountMoney(zaiquanAccount,huankuanMoney);
        int i1 = accountMapper.modifyMoney(zaiquanAccount.getId(), zaiquanAccount.getRemainMoney(), zaiquanAccount.getInMoney(), zaiquanAccount.getOutMoney());
        if( i1 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }
        //更新转出帐户中的数据
        subAccountMoney(findOutaccount,huankuanMoney);
        int i2 = accountMapper.modifyMoney(findOutaccount.getId(), findOutaccount.getRemainMoney(), findOutaccount.getInMoney(), findOutaccount.getOutMoney());
        if( i2 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }

        DoList doList = new DoList();
        doList.setUseId(accountTransfer.getUid());

        doList.setDoName("转账");
        doList.setDetail(accountTransfer.getDetail());
        doList.setRecordDate(accountTransfer.getTransferDate());
        doList.setRecordMoney(accountTransfer.getTransferMoney());
        doList.setAccId(zaiquanAccount.getId());
        doList.setAccOutId(findOutaccount.getId());
        doList.setFlag(6);
        doListMapper.insert(doList);
        return 1;
    }

    @Override
    @Transactional(readOnly = false,timeout = 30)
    public int shouzaiMoney(AccountTransfer accountTransfer) {

        //查找帐户
        Account zaiquanAccount = accountMapper.findbyId(accountTransfer.getAccountOutId());
        Account findInaccount = accountMapper.findbyId(accountTransfer.getAccountInId());

        if(zaiquanAccount.getRemainMoney().subtract(accountTransfer.getTransferMoney()).doubleValue() < 0  ){

            throw new RuntimeException("收债金额不对");
        }


        if (zaiquanAccount==null||findInaccount==null){

            throw new RuntimeException("数据发生错误");
        }
        int insert = accountTransferMapper.insert(accountTransfer);
        //
        if( insert <= 0){
            throw new RuntimeException("数据发生错误");
        }
        BigDecimal zaiquanMoney = accountTransfer.getTransferMoney();
        //更新负债帐户中的数据
        subAccountMoney(zaiquanAccount,zaiquanMoney);
        int i1 = accountMapper.modifyMoney(zaiquanAccount.getId(), zaiquanAccount.getRemainMoney(), zaiquanAccount.getInMoney(), zaiquanAccount.getOutMoney());
        if( i1 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }
        //更新转入帐户中的数据
        addUpdateAccountMoney(findInaccount,zaiquanMoney);
        int i2 = accountMapper.modifyMoney(findInaccount.getId(), findInaccount.getRemainMoney(), findInaccount.getInMoney(), findInaccount.getOutMoney());
        if( i2 <= 0){
            throw new RuntimeException("更新账户数据发生错误");
        }

        DoList doList = new DoList();
        doList.setUseId(accountTransfer.getUid());

        doList.setDoName("转账");
        doList.setDetail(accountTransfer.getDetail());
        doList.setRecordDate(accountTransfer.getTransferDate());
        doList.setRecordMoney(accountTransfer.getTransferMoney());
        doList.setAccId(findInaccount.getId());
        doList.setAccOutId(zaiquanAccount.getId());
        doList.setFlag(7);
        doListMapper.insert(doList);
        return 1;
    }


    @Override
    public List<Account> findByUid(int uid) {

        return accountMapper.findbyUid(uid);
    }

    private void subAccountMoney(Account account,BigDecimal zhicuMoney){

        account.setRemainMoney( MyMath.sub(account.getRemainMoney(),zhicuMoney));
        account.setOutMoney(  MyMath.add(account.getOutMoney(),zhicuMoney));

        logger.debug("支出的钱:{}",zhicuMoney.toString());
        logger.debug("更新后账户中的钱:{}",account);
    }

    private void addUpdateAccountMoney(Account account,BigDecimal shouruMoney){

        account.setRemainMoney( MyMath.add(account.getRemainMoney(),shouruMoney));
        account.setInMoney(  MyMath.add(account.getInMoney(),shouruMoney));

        logger.debug("支出的钱:{}",shouruMoney.toString());
        logger.debug("更新后账户中的钱:{}",account);
    }


}
